package com.xzakota.minesweeper;

import com.xzakota.minesweeper.log.XLogger;
import com.xzakota.minesweeper.msg.BaseMsg;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 通用 Socket 处理器
 *
 * @author Xzakota
 */
public class SocketHandler extends Thread {
    public int socketState = -1;
    public boolean isHandlerInit = false;
    protected Socket socket;
    protected InputStream reader;
    protected OutputStream writer;

    public SocketHandler() {
    }

    public SocketHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        super.run();

        try {
            reader = socket.getInputStream();
            writer = socket.getOutputStream();

            socketState = 1;
            isHandlerInit = true;
        } catch (Exception e) {
            socketState = 0;
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭所有流
     */
    public void closeStream() {
        try {
            if (reader != null) {
                reader.close();
            }
            if (writer != null) {
                writer.close();
            }

            reader = null;
            writer = null;
        } catch (IOException e) {
            XLogger.error(e);
        }
    }

    /**
     * 发送消息
     *
     * @param msg 消息
     */
    public void sendMsg(BaseMsg msg) {
        if (!isHandlerInit) {
            return;
        }

        if (writer != null) {
            try {
                ObjectOutputStream stream = new ObjectOutputStream(writer);
                stream.writeObject(msg);
                stream.flush();
            } catch (IOException e) {
                XLogger.warn("消息传输失败");
            }
        } else {
            XLogger.error("客户端 Socket 连接意外中断");
        }

    }

    /**
     * 关闭连接
     */
    public void close() {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
            if (!Thread.currentThread().isInterrupted()) {
                interrupt();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
